/**
 * 
 */
package org.asdt.core.internal.antlr;

import antlr.CommonAST;
import antlr.Token;
import antlr.collections.AST;

/**
 * @author Martin Schnabel mb0
 * 
 */
public class ASSourceAST extends CommonAST implements Comparable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -182805660463076688L;

	private OffsetInfo startOffset;

	private OffsetInfo endOffset;

	/**
	 * Creates a new source AST
	 */
	public ASSourceAST() {
		startOffset = OffsetInfo.getNullOffset();
		endOffset = OffsetInfo.getNullOffset();
	}

	/**
	 * @param tok
	 */
	public ASSourceAST(Token tok) {
		super(tok);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see antlr.collections.AST#initialize(antlr.collections.AST)
	 */
	public void initialize(AST ast) {
		super.initialize(ast);
		startOffset = new OffsetInfo(ast.getLine(), ast.getColumn());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see antlr.collections.AST#initialize(antlr.Token)
	 */
	public void initialize(Token t) {
		super.initialize(t);
		startOffset = new OffsetInfo(t.getLine(), t.getColumn());
		setEndOffset(t.getText());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see antlr.collections.AST#initialize(int, java.lang.String)
	 */
	public void initialize(int t, String txt) {
		setType(t);
		setText(txt);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(Object object) {
		if (object == null || !(object instanceof AST))
			return 0;
		AST that = (AST) object;
		if (this.getLine() < that.getLine())
			return -1;
		if (this.getLine() > that.getLine())
			return 1;
		if (this.getColumn() < that.getColumn())
			return -1;
		if (this.getColumn() > that.getColumn())
			return 1;
		return 0;
	}

	protected void setStartOffset(OffsetInfo info) {
		this.startOffset = new OffsetInfo(info.getLine(), info.getColumn());
	}

	protected void setStartOffset(AST ast) {
		this.startOffset = new OffsetInfo(ast.getLine(), ast.getColumn());
	}

	protected void setEndOffset(OffsetInfo info) {
		this.endOffset = new OffsetInfo(info.getLine(), info.getColumn());
	}

	protected void setEndOffset(AST ast) {
		if (ast instanceof ASSourceAST) {
			ASSourceAST as2ast = (ASSourceAST) ast;
			this.endOffset = new OffsetInfo(as2ast.getEndLine(), as2ast
					.getEndColumn());
		} else {
			this.endOffset = new OffsetInfo(ast.getLine(), ast.getColumn());
		}
	}

	protected void setEndOffset(String str) {
		if (str == null)
			str = "";
		int length = str == null ? 0 : str.length();
		this.endOffset = new OffsetInfo(startOffset.getLine(), startOffset
				.getColumn()
				+ length);
	}

	/**
	 * @return Returns the endOffset.
	 */
	public OffsetInfo getEndOffset() {
		return endOffset;
	}

	/**
	 * @return Returns the startOffset.
	 */
	public OffsetInfo getStartOffset() {
		return startOffset;
	}

	public int getLine() {
		return startOffset.getLine();
	}

	public int getColumn() {
		return startOffset.getColumn();
	}

	public int getEndLine() {
		return endOffset.getLine();
	}

	public int getEndColumn() {
		return endOffset.getColumn();
	}

	public boolean isRegion() {
		return !endOffset.isNull();
	}

	// ==== CONVENIENCE METHODS

	/**
	 * Returns the first child.
	 */
	public ASSourceAST getChild() {
		return getFirstChild() == null ? null : (ASSourceAST) getFirstChild();
	}

	/**
	 * Gets the next sibling.
	 */
	public ASSourceAST getSibling() {
		return getNextSibling() == null ? null : (ASSourceAST) getNextSibling();
	}
}
